package javacommon.base;


import static javacommon.util.SqlRemoveUtils.removeFetchKeyword;
import static javacommon.util.SqlRemoveUtils.removeSelect;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javacommon.ijdbc.IJdbcOperation;
import javacommon.ijdbc.RowMapper;
import javacommon.ijdbc.impl.DataSourceFactory;
import javacommon.ijdbc.impl.DataSourceFactory.DataSourceType;
import javacommon.ijdbc.impl.JdbcUtils;
import javacommon.util.StringUtils;
import javacommon.web.page.Page;
import javacommon.web.page.PageRequest;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 通用的jdbc Dao，实现了EntityDao中的部分方法，并提供了一些供子类使用的便利方法<br>
 * 其中值得注意的是<br> public Page<E> findAll(final PageRequest pageRequest)<br>
 * 参数为分页请求，封装了页码、每页条目数、排序列的信息<br> 返回值为Page对象，封装了一个“页”的数据及分页的相关信息，<br>
 * 获得数据用List list = page.getResult();
 * 
 * @author zhengwei lastmodified 2013年9月6日
 * @param <E>
 *            实体类型
 * @param <PK>
 *            主键值
 */
@SuppressWarnings("all")
public abstract class BaseJdbcDao<E> implements EntityDao<E> {
    /**
     * Logger for subclass
     */
    protected Logger log = LoggerFactory.getLogger(getClass());

    protected IJdbcOperation operation = JdbcUtils.getInstance();

    @Override
    public void deleteById(Serializable id)
        throws SQLException {
        String sql = "delete from " + getTableName() + " where " + getIdColumnName() + "=?";
        operation.execute(sql, id);
    }

    @Override
    public List<E> findAll()
        throws SQLException {
        String sql = "select * from " + getTableName();
        return operation.queryForList(sql, getEntityClass());
    }
    
    @Override
    public E getById(Serializable id)
        throws SQLException {
        String sql = "select * from " + getTableName() + " where " + getIdColumnName() + "=?";
        return (E) operation.queryForUniqueBean(sql, getEntityClass(), id);
    }
    /**
     * 得到全部数据(不带where条件),执行分页
     * 
     * @param pageRequest
     * @return
     * @throws SQLException
     */
    private Page<E> pageQuery(final PageRequest pageRequest)
        throws SQLException {
        StringBuilder queryString = new StringBuilder("SELECT * FROM ").append(getTableName());
        String sortString = StringUtils.deNull(pageRequest.getSortColumns(), "");
        if (!sortString.equals("")) {
            queryString.append(" ORDER BY " + StringUtils.deNull(pageRequest.getSortColumns(), ""));
        }

        return (Page<E>)pageQuery(queryString.toString(), pageRequest);

    }

    /**
     * 分页查询
     * 
     * @param sql
     *            内层查询的sql
     * @param pageRequest
     *            分页数据携带者
     * @param params
     *            sql的参数
     * @return
     * @throws SQLException
     * @see
     */
    protected Page<E> pageQuery(final String sql, final PageRequest pageRequest, Object... params)
        throws SQLException {
        final String countQuery = "SELECT count(*) " + removeSelect(removeFetchKeyword((sql)));
        return pageQuery(sql, countQuery, pageRequest);
    }

    /**
     * 构造全分页语句:<br> select * from <br> (select rownum rn ,t.* from <br> (内层查询) t <br> where
     * rownum<=pgSize*pgNum) <br> where rn>pgSize*(pgNum-1);<br>
     * 
     * @param sql
     *            内层查询的sql
     * @param countQuery
     *            查询出数量的sql
     * @param pageRequest
     *            分页数据携带者
     * @param params
     *            sql的参数
     * @return
     * @throws SQLException
     * @see
     */
    protected Page<E> pageQuery(final String sql, String countQuery,
                                final PageRequest pageRequest, Object... params)
        throws SQLException {
        StringBuilder query = new StringBuilder("select * from (select rownum rn ,t.* from (").append(
            sql).append(") t where rownum <= ").append(
            pageRequest.getPageNumber() * pageRequest.getPageSize());
        query.append(") where rn > ").append(
            pageRequest.getPageSize() * (pageRequest.getPageNumber() - 1));

        return executeQueryForPage(pageRequest, query.toString(), countQuery, params);
    }

    private Page executeQueryForPage(final PageRequest pageRequest, String query,
                                     String countQuery, Object... params)
        throws SQLException {
        Page page = new Page(pageRequest, operation.queryForInt(countQuery));
        if (page.getTotalCount() <= 0) {
            page.setResult(new ArrayList(0));
        } else {
//            page.setResult(operation.queryForList(query, getEntityClass(), params));
        	 page.setResult(operation.queryForList(query, getEntityClass(), params));
        }
        return page;
    }

    public IJdbcOperation getOperation() {
        return operation;
    }

    /**
     * 获取表名
     * 
     * @return
     */
    public abstract String getTableName();
    /**
     * 获取表名
     * 
     * @return
     */
    public abstract Class getEntityClass();
    /**
     * 返回主键列的列名
     * @return
     */
    public abstract String getIdColumnName();

//    public abstract RowMapper<E> getMapper();

	public void deleteByIds(String[] ids) throws SQLException {
	}
}
